import axios from 'axios'
import Qs from 'qs'
import { useAppStore } from '@/store/modules/app.js'
import { useSelectApiStore } from '@/store/modules/selectApi.js'
import { message } from 'ant-design-vue'
import { router } from '@/router/index.js'
import { debounce } from 'lodash-es'

const isDev = import.meta.env.DEV
const baseURL = import.meta.env.VITE_APP_BASE_API

const devTip = debounce(currentApi => {
  console.log(
    `%c 后端服务 %c ${currentApi.name} %c`,
    `background: #41b883; padding: 6px; border-radius: 4px 0 0 4px;  color: #fff`,
    `background: #35495e; padding: 6px; border-radius: 0 4px 4px 0;  color: #fff`,
    'background: transparent',
    currentApi.url
  )
}, 1000)

class ApiService {
  constructor() {
    this.axiosInstance = axios.create({
      // baseURL,
      // timeout: 5000
    })

    this.axiosInstance.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
    this.axiosInstance.defaults['unnecessaryBaseURL'] = false
    this.axiosInstance.defaults['unnecessaryToken'] = false
    this.axiosInstance.defaults['formData'] = false

    this.axiosInstance.interceptors.request.use(
      this.requestInterceptor.bind(this),
      this.requestErrorInterceptor.bind(this)
    )

    this.axiosInstance.interceptors.response.use(
      this.responseInterceptor.bind(this),
      this.responseErrorInterceptor.bind(this)
    )

    this.cancelTokenSource = axios.CancelToken.source()
  }

  requestInterceptor(config) {
    config.cancelToken = this.cancelTokenSource.token
    const appStore = useAppStore()
    if (appStore.token) {
      config.headers['Authorization'] = appStore.token
    }
    if (!config['unnecessaryBaseURL']) {
      if (isDev) {
        const selectApiStore = useSelectApiStore()
        config.baseURL = `${selectApiStore.currentApi.url}/api` || baseURL
        devTip(selectApiStore.currentApi)
      } else {
        config.baseURL = baseURL
      }
    }
    if (config['formData']) {
      config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
      config.transformRequest = [data => Qs.stringify(data)]
    }
    return config
  }

  requestErrorInterceptor(error) {
    // console.log(error)
    return Promise.reject(error)
  }

  responseInterceptor(response) {
    const appStore = useAppStore()
    if (response.status === 200) {
      const { code, msg } = response.data
      if (code === 401) {
        message.error(msg)
        appStore.logout()
        router.replace('/login')
      }
      return response.data
    }
    return Promise.reject(response)
  }

  responseErrorInterceptor(error) {
    const appStore = useAppStore()
    const currentRoutePath = router.currentRoute.value.fullPath
    const isLoginPath = currentRoutePath === '/login'
    const isLoginUrl = error.config.url === '/login'
    if (axios.isCancel(error)) {
      console.log('Request canceled:', error.message)
      return Promise.resolve({})
    }
    if (error.code === 'ERR_NETWORK' && !isLoginPath) {
      appStore.logout()
      // router.replace('/login')
    }
    if (error.message && !isLoginUrl) {
      message.error(error.message)
    }
    return Promise.reject(error)
  }

  cancelAllRequests() {
    this.cancelTokenSource.cancel('All requests canceled')
    this.cancelTokenSource = axios.CancelToken.source()
  }

  getAction(url, params) {
    return this.axiosInstance({
      url,
      params,
    })
  }

  getBlobAction(url, params) {
    return this.axiosInstance({
      responseType: 'blob',
      url,
      params,
    })
  }

  postAction(url, data) {
    return this.axiosInstance({
      method: 'post',
      url,
      data,
    })
  }

  uploadAction(url, data, onUploadProgress) {
    return this.axiosInstance({
      headers: {
        'Content-Type': 'multipart/form-data',
      },
      method: 'post',
      url,
      data,
      onUploadProgress,
    })
  }

  deleteAction(url, params) {
    return this.axiosInstance({
      method: 'delete',
      url,
      params,
    })
  }
}

const Service = new ApiService()
export default Service
